package js.dwim.domain;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

import javax.jdo.annotations.Element;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import js.dwim.server.Game;
import js.dwim.server.GameLogicException; 

import com.google.appengine.api.datastore.Key;

@PersistenceCapable( detachable = "true" )
public class WorldMap
        implements Serializable
{
    private static final long serialVersionUID = 1L;

    @PrimaryKey
    @Persistent( valueStrategy = IdGeneratorStrategy.IDENTITY )
    private Key key;
 
    @Persistent( mappedBy = "world", defaultFetchGroup = "true" )
    @Element( dependent = "true" )
    private List<MapNode> nodes = new LinkedList<MapNode>();

    @Persistent
    private int width;

    @Persistent
    private int height;

    public WorldMap()
    {
        this.width  = 1000;
        this.height = 1000;
        
        Player ai = Game.getAiPlayer();
        
        this.nodes.add( new MapNode( new Point2D( 50, 50 ), ai, this ) );
        this.nodes.add( new MapNode( new Point2D( 150, 150 ), ai, this ) );
    }

    public int getWidth()
    {
        return width;
    }
    
    public int getHeight()
    {
        return height;
    }
    
    public Key getKey()
    {
        return key;
    }

    public List<MapNode> getNodes()
    {
        return nodes;
    }
    
    public void setNodes( List<MapNode> nodes )
    {
        this.nodes = nodes;
    }

    public boolean hasPlayer( Player player )
    {
        for ( MapNode node : nodes )
        {
            if ( node.getPlayer().equals( player ) )
            {
                return true;
            }
        }
        return false;
    }

    public void addPlayer( Player player )
            throws GameLogicException
    {
        if ( hasPlayer( player ) )
        {
            throw new GameLogicException( "Player already present." );
        }
        Point2D spawn = new Point2D( 100, 100 );

        nodes.add( new MapNode( spawn, player, this ) );
    }

    public void removePlayer( Player player )
    {
        nodes.removeAll( getPlayerNodes( player ) );
    }
    
    public List<MapNode> getPlayerNodes( Player player )
    {
        LinkedList<MapNode> playerNodes = new LinkedList<MapNode>();

        for ( MapNode node : nodes )
        {
            if ( node.getPlayer().equals( player ) )
            {
                playerNodes.add( node );
            }
        }
        return playerNodes;
    }
    
    public void reset()
    {
        nodes.clear();
    }
}
